package com.guoyw.seata.dubbo.order.config;

import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import io.seata.spring.annotation.GlobalTransactionScanner;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import javax.sql.DataSource;

/**
 * 配置 seata数据源代理 和开启 global事务
 * author: guoyw
 * create: 2020-09-19 15:52
 **/

//@Configuration
public class SeataDataSourceAutoConfig{
  
  /**
   * autowired datasource config
   */
  @Autowired
  private DataSourceProperties dataSourceProperties;
  
  /**
   * init durid datasource
   *
   * @Return: druidDataSource  datasource instance
   */
  @Bean
  @Primary
  public DruidDataSource druidDataSource(){
    DruidDataSource druidDataSource = new DruidDataSource();
    druidDataSource.setUrl(dataSourceProperties.getUrl());
    druidDataSource.setUsername(dataSourceProperties.getUsername());
    druidDataSource.setPassword(dataSourceProperties.getPassword());
    druidDataSource.setDriverClassName(dataSourceProperties.getDriverClassName());
    druidDataSource.setInitialSize(0);
    druidDataSource.setMaxActive(180);
    druidDataSource.setMaxWait(60000);
    druidDataSource.setMinIdle(0);
    druidDataSource.setValidationQuery("Select 1 from DUAL");
    druidDataSource.setTestOnBorrow(false);
    druidDataSource.setTestOnReturn(false);
    druidDataSource.setTestWhileIdle(true);
    druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
    druidDataSource.setMinEvictableIdleTimeMillis(25200000);
    druidDataSource.setRemoveAbandoned(true);
    druidDataSource.setRemoveAbandonedTimeout(1800);
    druidDataSource.setLogAbandoned(true);
    return druidDataSource;
  }
  
//  /**
//   * init mybatis sqlSessionFactory
//   * @Param: dataSourceProxy  datasource proxy
//   * @Return: DataSourceProxy  datasource proxy
//   */
//  @Bean
//  public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
//    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
//    factoryBean.setDataSource(dataSource);
//    factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
//      .getResources("classpath*:/mapper/*.xml"));
//    return factoryBean.getObject();
//  }
  
  
  /**
   * init datasource proxy
   * @Param: druidDataSource  datasource bean instance
   * @Return: DataSourceProxy  datasource proxy
   */
  @Bean
  public DataSourceProxy dataSourceProxy(DruidDataSource druidDataSource){
    return new DataSourceProxy(druidDataSource);
  }
  
  /**
   * init mybatis sqlSessionFactory
   * @Param: dataSourceProxy  datasource proxy
   * @Return: DataSourceProxy  datasource proxy
   */
  @Bean
  public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy) throws Exception {
    SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
    factoryBean.setDataSource(dataSourceProxy);
    factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
      .getResources("classpath*:/mapper/*.xml"));
    factoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
    return factoryBean.getObject();
  }
  
  @Bean
  public DataSourceTransactionManager transactionManager(DataSourceProxy dataSourceProxy) {
    return new DataSourceTransactionManager(dataSourceProxy);
  }
  
  /**
   * init global transaction scanner
   *
   * @Return: GlobalTransactionScanner
   */
  @Bean
  public GlobalTransactionScanner globalTransactionScanner(){
    return new GlobalTransactionScanner("order-gts-seata-example", "my_test_tx_group");
  }
}
